#pragma once
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/epoll.h>

#include <vector>
#include "tcp_svr.hpp"

class EpollSvr
{
    public:
        EpollSvr()
        {
            epoll_fd_ = -1;
        }

        ~EpollSvr()
        {

        }

        bool InitSvr()
        {
            epoll_fd_ = epoll_create(10);
            if(epoll_fd_ < 0)
            {
                return false;
            }
            return true;
        }

        bool AddFd(int fd)
        {
            struct epoll_event ev;
            ev.events = EPOLLIN;
            ev.data.fd = fd;
            int ret = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &ev);
            if(ret < 0)
            {
                return false;
            }
            return true;
        }

        bool DeleteFd(int fd)
        {
            int ret = epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, NULL);
            if(ret < 0)
            {
                return false;
            }
            return true;
        }

        bool EpollWait(std::vector<TcpSvr>* out)
        {
            struct epoll_event fd_arr[10];
            int ret = epoll_wait(epoll_fd_, fd_arr, sizeof(fd_arr)/sizeof(fd_arr[0]), -1);
            if(ret < 0)
            {
                return false;
            }
            else if(ret == 0)
            {
                //只有带有超时时间的时候，epoll_wait超过超时时间才会有该返回值，否则不会有
                return false;
            }

            //ret 是返回的就绪的文件描述符个数
            if(ret > sizeof(fd_arr)/sizeof(fd_arr[0]))
            {
                ret = sizeof(fd_arr)/sizeof(fd_arr[0]);
            }

            //传入的数组大小是10， 
            //    1.就绪的文件描述符个数小于数组大小， ret就是就绪的文件描述符个数
            //    2.就绪的文件描述符个数大于数组大小，为了防止使用ret进行遍历的时候，访问数组越界导致程序崩溃，所以我们讲数据大小和返回值进行比较；
            
            for(int i = 0; i < ret; i++)
            {
                TcpSvr ts;
                ts.SetFd(fd_arr[i].data.fd);
                out->push_back(ts);
            }
            return true;
        }
    private:
        int epoll_fd_;
};
